package org.example;

import org.htmlunit.WebClient;
import org.htmlunit.html.*;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) throws Exception {
        try (final WebClient webClient = new WebClient()) {
            final HtmlPage page = webClient.getPage("https://fund.eastmoney.com/data/fundranking.html");
            MyDomChangeListener listener = new MyDomChangeListener();
            HtmlElement li = page.querySelector("#types li[data-typeid='000']");
            if (li != null) {
                HtmlElement targetDiv = page.querySelector(".dbtable");
                targetDiv.addDomChangeListener(listener);

                //点击按钮，等待页面加载完成
                listener.await(()->{
                    try {
                        HtmlPage newPage = li.click();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });

                HtmlElement selectLi = page.querySelector("#types .at");
                System.out.println(selectLi);

                boolean header = true;
                while (true){
                    HtmlTable table = page.querySelector("#dbtable");
                    System.out.println(table);

                    List<List<String>> lists = parseTableToList(table);
                    if(!header){
                        lists = lists.subList(1,lists.size());
                    }else{
                        header = false;
                        List<String> subList = lists.get(0);
                        for (int i = 0; i < subList.size(); i++) {
                            String original = subList.get(i);
                            String replaced = original.replaceAll("\\s+", "");
                            subList.set(i, replaced);
                        }
                    }
                    writeCsv(lists,"out.csv");

                    //查找当前页
                    HtmlElement curElement = page.querySelector("#pagebar .cur");
                    // 获取下一页
                    DomElement label = curElement.getNextElementSibling();

                    if (label != null) {

                        String classValue = label.getAttribute("class");
                        //判断最后一页返回
                        if(Arrays.asList(classValue.split(" ")).contains("end")){
                            break;
                        }
                        //点击按钮，等待页面加载完成
                        listener.await(()->{
                            try {
                                label.click();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        });
                    } else {
                        throw new RuntimeException("错误");
                    }

                }

            } else {
                System.out.println("未找到目标 <li> 元素");
            }
        }
    }

    /**
     * 监听元素，
     */
    static class MyDomChangeListener implements DomChangeListener {

        private final ConcurrentLinkedQueue<ArrayBlockingQueue<Long>> queue  = new ConcurrentLinkedQueue<>();

        @Override
        public void nodeAdded(DomChangeEvent domChangeEvent) {
            if(domChangeEvent.getChangedNode() instanceof HtmlTable){
                ArrayBlockingQueue<Long> peek = queue.peek();
                if(peek!=null){
                    peek.clear();
                    long l = System.currentTimeMillis();
                    peek.offer(l);
                }
            }
        }

        @Override
        public void nodeDeleted(DomChangeEvent domChangeEvent) {

        }

        public void await(Runnable action) throws InterruptedException {
            ArrayBlockingQueue<Long> arrayQueue = new ArrayBlockingQueue<>(1);
            queue.clear();
            queue.offer(arrayQueue);
            action.run();
            arrayQueue.poll(5, TimeUnit.SECONDS);
        }

    }

    public static List<List<String>> parseTableToList(HtmlTable table) {
        List<List<String>> result = new ArrayList<>();

        // 遍历所有行（跳过表头，若需要表头可移除条件）
        for (HtmlTableRow row : table.getRows()) {
            // 跳过表头行（根据实际需求调整）
            if (row.getCells().isEmpty()) {
                continue;
            }

            List<String> rowData = new ArrayList<>();
            for (HtmlTableCell cell : row.getCells()) {
                rowData.add(cell.getTextContent().trim()); // 提取单元格文本并去除空格
            }
            result.add(rowData);
        }
        return result;
    }

    public static void writeCsv(List<List<String>> tableData, String filePath) throws IOException {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath,true))) {
            for (List<String> row : tableData) {
                // 使用逗号分隔，并对可能含有逗号或引号的字段加引号
                String csvRow = row.stream()
                        .map(cell -> {
                            String escaped = cell.replace("\"", "\"\"");
                            return "\"" + escaped + "\"";
                        })
                        .collect(Collectors.joining(","));
                writer.write(csvRow);
                writer.newLine();
            }
        }
    }
}